"""旋钮控制模块"""
import threading
import time
import subprocess
import os
from .config import GPIO_CONFIG, setup_logging

try:
    if GPIO_CONFIG.get('is_orangepi', False):
        import OPi.GPIO as GPIO
    else:
        class MockGPIO:
            BOARD = 'BOARD'
            IN = 'IN'
            OUT = 'OUT'
            PUD_UP = 'PUD_UP'
            HIGH = 1
            LOW = 0
            @staticmethod
            def setmode(mode): pass
            @staticmethod
            def setup(pin, mode, pull_up_down=None): pass
            @staticmethod
            def input(pin): return 1
            @staticmethod
            def add_event_detect(pin, edge, callback=None, bouncetime=None): pass
            @staticmethod
            def remove_event_detect(pin): pass
            @staticmethod
            def cleanup(): pass
        GPIO = MockGPIO()
except Exception:
    class MockGPIO:
        BOARD = 'BOARD'
        IN = 'IN'
        OUT = 'OUT'
        PUD_UP = 'PUD_UP'
        HIGH = 1
        LOW = 0
        @staticmethod
        def setmode(mode): pass
        @staticmethod
        def setup(pin, mode, pull_up_down=None): pass
        @staticmethod
        def input(pin): return 1
        @staticmethod
        def add_event_detect(pin, edge, callback=None, bouncetime=None): pass
        @staticmethod
        def remove_event_detect(pin): pass
        @staticmethod
        def cleanup(): pass
    GPIO = MockGPIO()

class RotaryController:
    """旋钮控制器"""
    
    def __init__(self, tts_callback=None, shutdown_callback=None):
        self.logger = setup_logging('RotaryController')
        self.tts_callback = tts_callback
        self.shutdown_callback = shutdown_callback
        
        # GPIO引脚配置（RC充放电模式）
        self.rc_pin = GPIO_CONFIG['rotary_clk_pin']  # 使用GPIO 17进行RC充放电测量
        
        # 音量控制
        self.current_volume = 50  # 默认音量50%
        self.volume_step = GPIO_CONFIG['volume_step']
        self.max_volume = GPIO_CONFIG['max_volume']
        self.min_volume = GPIO_CONFIG['min_volume']
        
        # RC充放电状态
        self.last_rc_time = 0
        self.rc_change_threshold = 0.1  # RC时间变化阈值（秒）
        self.running = False
        
        # 播报频率控制
        self.last_announce_time = 0
        self.announce_interval = 2.0  # 2秒内不重复播报
        
        # 低音量关机控制（已禁用）
        # self.shutdown_volume_threshold = GPIO_CONFIG.get('shutdown_volume_threshold', 10)
        
        # 初始化GPIO
        self.gpio_init_failed = False
        self.last_gpio_error_time = 0
        self.gpio_error_interval = 30  # 30秒内不重复报错
        self._init_gpio()
        
        self.logger.info("旋钮控制器初始化完成")
    
    def _init_gpio(self):
        """初始化GPIO"""
        try:
            if GPIO_CONFIG.get('is_orangepi', False):
                # RC充放电模式初始化
                GPIO.setup(self.rc_pin, GPIO.OUT)
                GPIO.output(self.rc_pin, GPIO.LOW)  # 初始化为低电平
                
                self.logger.info(f"RC充放电模式初始化 - GPIO: {self.rc_pin}")
                self.logger.info("音量范围: 0-100%（低音量关机功能已禁用）")
                self.logger.info("使用RC充放电时间测量电位器阻值")
                self.gpio_init_failed = False
            else:
                self.logger.info("开发环境模式，使用模拟RC测量")
                self.gpio_init_failed = False
        except Exception as e:
            self.gpio_init_failed = True
            current_time = time.time()
            # 控制错误报告频率
            if current_time - self.last_gpio_error_time > self.gpio_error_interval:
                self.logger.error(f"电位器初始化失败: {e}")
                self.last_gpio_error_time = current_time
            # 使用模拟值作为备选
            self.last_volume_reading = 50
    
    def start(self):
        """启动旋钮监控"""
        if self.running:
            return
        
        self.running = True
        self.monitor_thread = threading.Thread(target=self._monitor_loop)
        self.monitor_thread.daemon = True
        self.monitor_thread.start()
        
        # 获取并播报当前音量
        self.current_volume = self._get_system_volume()
        self.logger.info(f"旋钮控制器已启动，当前音量: {self.current_volume}%")
    
    def stop(self):
        """停止旋钮监控"""
        self.running = False
        if hasattr(self, 'monitor_thread'):
            self.monitor_thread.join(timeout=2)
        
        try:
            if GPIO_CONFIG.get('is_orangepi', False):
                GPIO.remove_event_detect(self.clk_pin)
                GPIO.remove_event_detect(self.sw_pin)
        except Exception as e:
            self.logger.error(f"清理旋钮GPIO失败: {e}")
        
        self.logger.info("旋钮控制器已停止")
    
    def _monitor_loop(self):
        """监控循环"""
        while self.running:
            try:
                # 检查RC充放电时间（音量调节）
                self._check_rc_timing()
                
                time.sleep(0.5)  # 500ms检查间隔（降低检查频率）
                
            except Exception as e:
                self.logger.error(f"电位器监控循环错误: {e}")
                time.sleep(0.5)
    
    def _check_rc_timing(self):
        """检查RC充放电时间"""
        try:
            # 如果GPIO初始化失败，跳过检查
            if self.gpio_init_failed:
                return
            
            # 测量RC充放电时间
            rc_time = self._measure_rc_time()
            
            # 检查是否有足够的变化（避免抖动）
            if abs(rc_time - self.last_rc_time) >= self.rc_change_threshold:
                # 将RC时间转换为音量值
                volume = self._rc_time_to_volume(rc_time)
                self._set_volume_from_rc(volume)
                self.last_rc_time = rc_time
            
        except Exception as e:
            current_time = time.time()
            # 控制错误报告频率
            if current_time - self.last_gpio_error_time > self.gpio_error_interval:
                self.logger.error(f"检查RC充放电失败: {e}")
                self.last_gpio_error_time = current_time
            # 标记GPIO失败
            self.gpio_init_failed = True
    
    def _measure_rc_time(self):
        """测量RC充放电时间"""
        try:
            if GPIO_CONFIG.get('is_orangepi', False):
                # RC充放电时间测量
                # 1. 设置为输出模式，充电
                GPIO.setup(self.rc_pin, GPIO.OUT)
                GPIO.output(self.rc_pin, GPIO.HIGH)
                time.sleep(0.01)  # 充电10ms
                
                # 2. 设置为输入模式，开始放电计时
                GPIO.setup(self.rc_pin, GPIO.IN)
                start_time = time.time()
                
                # 3. 等待放电到低电平（最多等待1秒）
                timeout = 1.0
                while GPIO.input(self.rc_pin) == GPIO.HIGH:
                    if time.time() - start_time > timeout:
                        break
                    time.sleep(0.0001)  # 0.1ms精度
                
                discharge_time = time.time() - start_time
                return min(discharge_time, timeout)  # 限制最大时间
            else:
                # 开发环境返回固定值
                return self.last_rc_time if self.last_rc_time > 0 else 0.5
        except Exception as e:
            self.logger.error(f"RC时间测量失败: {e}")
            return self.last_rc_time if self.last_rc_time > 0 else 0.5
    
    def _rc_time_to_volume(self, rc_time):
        """将RC时间转换为音量百分比"""
        # RC时间范围通常在0.01-1.0秒之间
        # 映射到0-100%音量
        min_time = 0.01  # 最小RC时间（对应100%音量）
        max_time = 1.0   # 最大RC时间（对应0%音量）
        
        # 限制RC时间范围
        rc_time = max(min_time, min(max_time, rc_time))
        
        # 反向映射：时间越短，音量越大
        volume = 100 - int(((rc_time - min_time) / (max_time - min_time)) * 100)
        return max(self.min_volume, min(self.max_volume, volume))
    
    def _set_volume_from_rc(self, volume_value):
        """根据RC时间设置音量"""
        try:
            # 音量值已经是0-100范围
            new_volume = int(volume_value)
            new_volume = max(self.min_volume, min(self.max_volume, new_volume))
            
            if new_volume != self.current_volume:
                old_volume = self.current_volume
                self.current_volume = new_volume
                
                # 设置系统音量（静默模式，减少错误日志）
                self._set_system_volume_silent(self.current_volume)
                
                # 控制播报频率
                current_time = time.time()
                if current_time - self.last_announce_time > self.announce_interval:
                    # 语音播报音量变化
                    volume_text = f"音量{self.current_volume}%"
                    self.logger.info(volume_text)
                    
                    if self.tts_callback:
                        self.tts_callback(volume_text)
                    
                    self.last_announce_time = current_time
                
                # 低音量关机功能已暂时禁用
                # self._check_low_volume()
                
        except Exception as e:
            self.logger.error(f"设置RC音量失败: {e}")
    

    
    def _adjust_volume(self, increase):
        """调节音量"""
        try:
            old_volume = self.current_volume
            
            if increase:
                self.current_volume = min(self.max_volume, self.current_volume + self.volume_step)
            else:
                self.current_volume = max(self.min_volume, self.current_volume - self.volume_step)
            
            if self.current_volume != old_volume:
                # 设置系统音量
                self._set_system_volume(self.current_volume)
                
                # 语音播报音量变化
                direction = "增加" if increase else "减少"
                volume_text = f"音量{direction}到{self.current_volume}%"
                self.logger.info(volume_text)
                
                if self.tts_callback:
                    self.tts_callback(volume_text)
                
                # 低音量关机功能已暂时禁用
                # self._check_low_volume()
                
        except Exception as e:
            self.logger.error(f"调节音量失败: {e}")
    
    def _check_low_volume(self):
        """检查低音量状态"""
        try:
            # 检查是否需要关机
            if self.current_volume <= self.shutdown_volume_threshold:
                shutdown_text = f"音量过低({self.current_volume}%)，系统将自动关机"
                self.logger.warning(shutdown_text)
                
                if self.tts_callback:
                    self.tts_callback(shutdown_text)
                
                # 等待语音播报完成后关机
                time.sleep(2)
                self._handle_shutdown()
                return
                
        except Exception as e:
            self.logger.error(f"检查低音量状态失败: {e}")
    
    def _toggle_mute(self):
        """切换静音状态"""
        try:
            # 尝试多种音频控制器进行静音切换
            success = False
            mute_text = "静音"
            
            for control in ['Master', 'PCM', 'Speaker', 'Headphone']:
                try:
                    # 获取当前静音状态
                    result = subprocess.run(['amixer', 'get', control], 
                                          capture_output=True, text=True, check=True)
                    
                    if '[off]' in result.stdout:
                        # 当前静音，取消静音
                        subprocess.run(['amixer', 'set', control, 'unmute'], check=True)
                        mute_text = "取消静音"
                    else:
                        # 当前未静音，设置静音
                        subprocess.run(['amixer', 'set', control, 'mute'], check=True)
                        mute_text = "静音"
                    
                    success = True
                    break
                    
                except subprocess.CalledProcessError:
                    continue
            
            if success:
                self.logger.info(f"音量状态: {mute_text}")
                
                if self.tts_callback and mute_text == "取消静音":
                    self.tts_callback(mute_text)
            else:
                self.logger.warning("无法找到可用的音频控制器进行静音切换")
                
        except Exception as e:
            self.logger.error(f"切换静音失败: {e}")
    
    def _handle_shutdown(self):
        """处理关机"""
        try:
            shutdown_text = "系统将在5秒后关机"
            self.logger.warning(shutdown_text)
            
            if self.tts_callback:
                self.tts_callback(shutdown_text)
            
            # 等待语音播报完成
            time.sleep(3)
            
            # 调用关机回调
            if self.shutdown_callback:
                self.shutdown_callback()
            
            # 执行关机命令
            if GPIO_CONFIG.get('is_orangepi', False):
                subprocess.run(['sudo', 'shutdown', '-h', 'now'], check=True)
            else:
                self.logger.info("开发环境模式，跳过实际关机")
                
        except Exception as e:
            self.logger.error(f"关机处理失败: {e}")
    
    def _get_system_volume(self):
        """获取系统音量"""
        try:
            # 尝试多种音频控制器
            for control in ['Master', 'PCM', 'Speaker', 'Headphone']:
                try:
                    result = subprocess.run(['amixer', 'get', control], 
                                          capture_output=True, text=True, check=True)
                    
                    # 解析音量百分比
                    import re
                    match = re.search(r'\[(\d+)%\]', result.stdout)
                    if match:
                        return int(match.group(1))
                except subprocess.CalledProcessError:
                    continue
            
            return 50  # 默认音量
            
        except Exception as e:
            self.logger.error(f"获取系统音量失败: {e}")
            return 50
    
    def _set_system_volume(self, volume):
        """设置系统音量"""
        try:
            # 尝试多种音频控制器
            success = False
            for control in ['Master', 'PCM', 'Speaker', 'Headphone']:
                try:
                    subprocess.run(['amixer', 'set', control, f'{volume}%'], check=True)
                    success = True
                    break
                except subprocess.CalledProcessError:
                    continue
            
            if not success:
                # 如果amixer失败，尝试使用alsactl
                try:
                    subprocess.run(['alsactl', 'store'], check=False)
                    self.logger.warning(f"amixer设置失败，音量可能未生效: {volume}%")
                except:
                    self.logger.warning(f"所有音量控制方法都失败，音量设置为: {volume}%")
            
        except Exception as e:
            self.logger.error(f"设置系统音量失败: {e}")
    
    def _set_system_volume_silent(self, volume):
        """静默设置系统音量（减少错误日志）"""
        try:
            # 尝试多种音频控制器
            success = False
            for control in ['Master', 'PCM', 'Speaker', 'Headphone']:
                try:
                    subprocess.run(['amixer', 'set', control, f'{volume}%'], 
                                 check=True, capture_output=True)
                    success = True
                    break
                except subprocess.CalledProcessError:
                    continue
            
            # 静默模式：只在第一次失败时记录警告
            if not success and not hasattr(self, '_volume_warning_shown'):
                self.logger.warning("音频控制器不可用，音量调节可能无效")
                self._volume_warning_shown = True
            
        except Exception:
            # 静默处理异常，避免频繁错误日志
            pass
    
    def get_current_volume(self):
        """获取当前音量"""
        return self.current_volume
    
    def set_volume(self, volume):
        """设置音量"""
        volume = max(self.min_volume, min(self.max_volume, volume))
        self.current_volume = volume
        self._set_system_volume(volume)
        
        volume_text = f"音量设置为{volume}%"
        self.logger.info(volume_text)
        
        if self.tts_callback:
            self.tts_callback(volume_text)